package com.fulihui.systemcore.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.near.servicesupport.request.TRequest;
import org.near.servicesupport.result.BaseResult;
import org.near.servicesupport.result.ResultBuilder;
import org.near.servicesupport.result.TSingleResult;
import org.near.servicesupport.util.ConditionValidator;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.fulihui.systemcore.api.MenuService;
import com.fulihui.systemcore.dal.helper.SortBean;
import com.fulihui.systemcore.dto.MenuDTO;
import com.fulihui.systemcore.repository.MenuRepository;
import com.fulihui.systemcore.request.menu.MenuCreateRequest;
import com.fulihui.systemcore.request.menu.MenuDeleteRequest;
import com.fulihui.systemcore.request.menu.MenuUpdateRequest;
import com.fulihui.systemcore.request.menu.QueryChildMenuRequest;
import com.fulihui.systemcore.request.menu.QueryMenuByCodeRequest;
import com.fulihui.systemcore.request.menu.QueryMenuByIdRequest;
import com.fulihui.systemcore.request.menu.QueryTopMenuRequest;
import com.fulihui.systemcore.request.menu.SortRequest;
import com.fulihui.systemcore.response.menu.QueryMenuResponse;
import com.fulihui.systemcore.response.menu.QueryMenuSingleResponse;
import com.fulihui.systemcore.util.PinYinUtil;

/**
 * @author leeson 2016年5月17日 下午3:16:05
 *
 */
@Component("menuService")
public class MenuServiceImpl implements MenuService {
    @Autowired
    private MenuRepository menuRepository;

    @Override
    public TSingleResult<QueryMenuResponse> queryTopMenu(TRequest<QueryTopMenuRequest> request) {
        ConditionValidator.validate(request.getCondition());

        List<MenuDTO> menuList = menuRepository.queryTopMenu(
            request.getCondition().getIsConstainChild(), request.getCondition().getProjectCode());

        QueryMenuResponse response = new QueryMenuResponse();
        response.setMenuList(menuList);

        return ResultBuilder.succTSingle(response);
    }

    @Override
    public TSingleResult<QueryMenuResponse> queryChildMenu(TRequest<QueryChildMenuRequest> request) {
        ConditionValidator.validate(request.getCondition());

        List<MenuDTO> menuList = menuRepository
            .queryChildMenu(request.getCondition().getMenuCode());

        QueryMenuResponse response = new QueryMenuResponse();
        response.setMenuList(menuList);

        return ResultBuilder.succTSingle(response);
    }

    @Override
    public BaseResult sort(TRequest<SortRequest> request) {
        ConditionValidator.validate(request.getCondition());

        Map<Integer, Integer> idAndIndexMap = new HashMap<>();

        List<SortBean> sortList = JSON.parseArray(request.getCondition().getSortJson(),
            SortBean.class);
        for (int i = 1; i <= sortList.size(); i++) {
            idAndIndexMap.put(sortList.get(i - 1).getId(), i);
        }

        menuRepository.batchUpdateIndex(idAndIndexMap);

        return ResultBuilder.succ(BaseResult.class);
    }

    @Transactional
    @Override
    public BaseResult create(TRequest<MenuCreateRequest> request) {
        MenuCreateRequest condition = request.getCondition();

        ConditionValidator.validate(condition);

        MenuDTO record = new MenuDTO();
        BeanUtils.copyProperties(condition, record);

        //设置code
        String menuCode = PinYinUtil.toPinYin(condition.getName());
        if (null == menuCode) {
            return ResultBuilder.fail(BaseResult.class, 102, "[name] include special characters.");
        }
        //确保所有都转为大写
        menuCode = menuCode.toUpperCase();
        record.setCode(menuCode);
        //设置index
        int maxIndex = menuRepository.maxIndex(condition.getProjectCode(),
            condition.getParentCode());
        maxIndex++;
        record.setIndex(maxIndex);

        try {
            menuRepository.insert(record);
        } catch (Exception e) {
            return ResultBuilder.fail(BaseResult.class, 103, "菜单名称已经存在.");
        }

        return ResultBuilder.succ(BaseResult.class);
    }

    @Override
    public BaseResult update(TRequest<MenuUpdateRequest> request) {
        MenuUpdateRequest condition = request.getCondition();

        ConditionValidator.validate(condition);

        MenuDTO record = new MenuDTO();
        BeanUtils.copyProperties(condition, record);
        record.setId(condition.getMenuId());

        try {
            menuRepository.update(record);
        } catch (Exception e) {
            return ResultBuilder.fail(BaseResult.class, 101, "菜单名称已经存在.");
        }

        return ResultBuilder.succ(BaseResult.class);
    }

    @Override
    public BaseResult delete(TRequest<MenuDeleteRequest> request) {
        MenuDeleteRequest condition = request.getCondition();

        ConditionValidator.validate(condition);

        menuRepository.delete(condition.getMenuId());

        return ResultBuilder.succ(BaseResult.class);
    }

    @Override
    public TSingleResult<QueryMenuSingleResponse> queryById(TRequest<QueryMenuByIdRequest> request) {
        QueryMenuByIdRequest condition = request.getCondition();

        ConditionValidator.validate(condition);

        MenuDTO menu = menuRepository.queryById(condition.getMenuId());

        QueryMenuSingleResponse value = new QueryMenuSingleResponse();
        value.setMenu(menu);
        return ResultBuilder.succTSingle(value);
    }

    @Override
    public TSingleResult<QueryMenuSingleResponse> queryByCode(TRequest<QueryMenuByCodeRequest> request) {
        QueryMenuByCodeRequest condition = request.getCondition();

        ConditionValidator.validate(condition);

        MenuDTO menu = menuRepository.queryByCode(condition.getMenuCode());

        QueryMenuSingleResponse value = new QueryMenuSingleResponse();
        value.setMenu(menu);
        return ResultBuilder.succTSingle(value);
    }
}